<!--author: lms-->

<template>
  <el-dialog
    width="769px"
    :visible.sync="visible"
  >
    <el-table
      :data="settingList"
      border
      fit
      max-height="600"
      style="width: 100%"
      :cell-style="cellStyle"
    >
      <el-table-column
        prop="label"
        label="属性名称"
        align="center"
        width="120">
      </el-table-column>
      <el-table-column
        prop="type"
        label="属性类别"
        align="center"
        width="120">
        <template slot-scope="{ row }">
          <span v-if="row.type==='normal'">
            默认
          </span>
          <span v-if="row.type==='index'">
            索引
          </span>
          <span v-if="row.type==='expand'">
            展开
          </span>
          <span v-if="row.type==='selection'">
            多选
          </span>
        </template>
      </el-table-column>
      <el-table-column
        label="固定状态"
        align="center"
        width="220">
        <template slot-scope="{ row }">
          <el-radio-group v-model="row.fixed" size="mini" @change="switchFixedStatus(row)">
            <el-radio-button label="left">左</el-radio-button>
            <el-radio-button :label="undefined">无</el-radio-button>
            <el-radio-button label="right">右</el-radio-button>
          </el-radio-group>
        </template>
      </el-table-column>
      <el-table-column
        label="展示状态"
        align="center"
        width="120">
        <template slot-scope="{ row }">
          <el-switch v-model="row.ifShow" @change="switchDisplayStatus(row)" />
        </template>
      </el-table-column>

      <el-table-column label="操作" align="center" width="140">
        <template slot-scope="{ row, $index }">
          <el-button :class="{hidden: $index===0}"
                     type="primary"
                     icon="el-icon-top"
                     size="mini"
                     @click="up(row)" />
          <el-button :class="{hidden: $index===settingList.length-1}"
                     type="primary"
                     icon="el-icon-bottom"
                     size="mini" plain
                     @click="down(row)">
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <span slot="footer" class="dialog-footer">
      <el-button plain @click="reset">重置</el-button>
      <el-button plain type="info" @click="visible=false">关闭</el-button>
    </span>
  </el-dialog>
</template>

<script>
import RBootTableStoreHelper from '../../helper/RBootTableStoreHelper'

export default {
  data() {
    return {
      settingList: []
    }
  },
  props: {
    elementList: {
      type: Array,
      required: true
    },
    ifOpen: {
      type: Boolean,
      required: true
    },
    ifCache: {
      type: Boolean,
      default: true
    },
    closeRef: {
      type: Function,
      required: true
    },
    syncRef: {
      type: Function,
      required: true
    }
  },
  computed: {
    visible: {
      get() {
        return this.ifOpen
      },
      set(visible) {
        if (visible === false) {
          this.closeRef()
        }
      }
    },
    defaultList: {
      get() {
        const usedList = this.elementList.filter((element) => {
          return element.componentOptions
        })

        const defaultList = []
        for (const element of usedList) {
          if (!element.componentOptions) {
            continue
          }
          const props = element.componentOptions?.propsData

          defaultList.push({
            element: element,
            label: props.label || '-',
            type: props.type || 'normal',
            fixed: props.fixed,
            ifShow: true
          })
        }
        return defaultList
      }
    }
  },
  watch: {
    settingList: function(settingList) {
      if (this.ifCache) {
        // 保存到本地
        RBootTableStoreHelper.store(this.$route.path, settingList)
      }

      // 同步给父组件
      this.syncRef(settingList)
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    /**
     * 初始化表格结构
     * @private
     */
    init() {
      if (!this.ifCache) {
        this.settingList = this.defaultList
        return
      }

      const storeList = RBootTableStoreHelper.fetch(this.$route.path)
      /**
       * 1. 先处理本地无缓存的情况
       */
      if (!storeList) {
        this.settingList = this.defaultList
        return
      }

      /**
       * 2. 再处理本地有缓存的情况
       */
      this.settingList = storeList

      /**
       * 3.同步节点和缓存
       */
      for (let setting of this.settingList) {
        setting.deleted = true
      }
      this.defaultList.forEach((def, index) => {
        let settingIndex = this.settingList.findIndex((setting) => {
          return setting.label === def.label
        })
        if (settingIndex >= 0) {
          // 如果找到了，就更新
          this.$set(this.settingList, settingIndex, {
            ...def,
            ...this.settingList[settingIndex],
            deleted: false
          })
        } else {
          // 如果找不到，就新增
          this.settingList.splice(index, 0, {
            ...def,
            deleted: false
          })
        }
      })
      // 删除settingList比defaultList多的那些（旧字段）
      this.settingList = this.settingList.filter((setting) => {
        return !setting.deleted
      })
    },
    reset() {
      this.$confirm('是否重置表格结构？')
        .then(_ => {
          this.settingList = this.defaultList
        })
    },
    cellStyle({ row }) {
      if (row.type === 'selection') {
        return `font-weight:bolder!important;color: blue;background: snow;`
      } else if (row.fixed) {
        return `font-weight:bolder!important;color: red;background: snow;`
      }
    },
    /**
     * 切换列的固定状态
     * @param setting
     */
    switchFixedStatus(setting) {
      this.$set(this.settingList, this._pos(setting), setting)
    },
    /**
     * 切换列的显隐状态
     * @param setting
     */
    switchDisplayStatus(setting) {
      this.$set(this.settingList, this._pos(setting), setting)
    },
    /**
     * 上移元素
     * @param setting
     */
    up(setting) {
      const target = this._prevItem(setting)
      /*
       * 交换位置
       */
      let targetPos = this._pos(target)
      let settingPos = this._pos(setting)

      this.$set(this.settingList, targetPos, setting)
      this.$set(this.settingList, settingPos, target)
    },
    /**
     * 下移元素
     * @param setting
     */
    down(setting) {
      this.up(this._nextItem(setting))
    },
    _pos(setting) {
      for (let index in this.settingList) {
        index = Number.parseInt(index)
        const item = this.settingList[index]
        if (item.label === setting.label) {
          return index
        }
      }
    },
    /**
     * 获得下一个元素
     * @param setting
     * @returns {null}
     * @private
     */
    _nextItem(setting) {
      const pos = this._pos(setting)
      if (pos === this.settingList.length - 1) {
        return null
      }
      return this.settingList[pos + 1]
    },
    /**
     * 获得上一个元素
     * @param setting
     * @returns {null}
     * @private
     */
    _prevItem(setting) {
      const pos = this._pos(setting)
      if (pos === 0) {
        return null
      }
      return this.settingList[pos - 1]
    }
  }
}
</script>

<style lang="scss" scoped>
::v-deep .el-dialog__body {
  padding-bottom: 10px;
  padding-top: 10px;
}

::v-deep .el-dialog__footer {
  padding: 0 20px 10px;
}

::v-deep .el-dialog__headerbtn {
  display: none;
}

::v-deep .el-dialog__header {
  text-align: right;
  padding-top: 10px;
  padding-bottom: 0;
}
</style>
